package com.taobao.snowsnow.taobao;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>淘宝的SKU解析类
 * SKU包括商品品种,商品颜色,商品规格
 * @author Tux
 *
 * 创建时间: 2011-7-24 上午11:29:21
 * 修改时候: 2011--10-21 下午 23:30:33
 */
public class SkuParse {
	
	// 颜色
	private static final String COLORKEYWORDS = "灰|蓝|咖啡|红|粉|黄|白|绿|印花|黑|金|银|青玉|藕|紫|裸|槟";
	
	// 扣饰类别
	private static final String PIN = "胸针|发夹|发卡|发叉梳";
	
	// 蝴蝶结层数
	private static final String LAYERS = "单层|双层";
	
	// 蝴蝶结类别
	private static final String TYPES = "鞋花|头饰|衣饰";
	
	// 蝴蝶结材料
	private static final String MATERIAL = "缎带|罗纹";
	
	// 不良品
	private static final String REJECT = "瑕疵|溢胶|歪斜";
	
	public static final String[] SKUTITLE = {"颜色", "类型", "层数", "加钻", "原材料", "扣饰", "不良品", "规格"};
	
	private String color, type, specs,layer, veil, jewel, material, pin, reject;
	
	public SkuParse(String parseString) {
		parseProperty(parseString);
	}

	/**
	 * 按行解析
	 * @param fileName
	 * @throws IOException
	 */
	public void parse(String fileName) throws IOException {
		BufferedReader reader = readFile(fileName);    
		String tempString = null;  
		
		String colorRegEx, typeRegEx, veilRegEx, layerRegEx, rejectRegEx, materialRegEx, pinRegEx, specsRegEx = "";
		
		colorRegEx = "[\u4e00-\u9fa5]*(" + COLORKEYWORDS + ")[色]?";
		pinRegEx = "(" + PIN + ")";
		layerRegEx = "(" + LAYERS + ")";
		typeRegEx = "(" + TYPES + ")";
		materialRegEx = "(" + MATERIAL + ")";
		veilRegEx = "(" + COLORKEYWORDS + "|蒙)纱";
		specsRegEx = "(\\w*\\*\\w*cm|\\d+[\\u4e00-\\u9fa5]*高|高度\\d+[\\u4e00-\\u9fa5]*|宽\\w*\\x20高\\w*|\\w+[\\u4e00-\\u9fa5]*宽)";
		rejectRegEx = "(" + REJECT + ")";
		
		List<String> list = new ArrayList<String>();
		
		while ((tempString = reader.readLine()) != null) {  
			color = getValue(tempString, colorRegEx);
			type = getValue(tempString, typeRegEx);
			veil = getValue(tempString, veilRegEx);
			layer = getValue(tempString, layerRegEx);
			material = getValue(tempString, materialRegEx);
			pin = getValue(tempString, pinRegEx);
			specs = getValue(tempString, specsRegEx);
			reject = getValue(tempString, rejectRegEx);
			jewel = getValue(tempString, "钻");
			
			if(reject != null) {
//				String s = width(hwidth(reject));
				String s = reject;
				if(!list.contains(s)) {
					list.add(s);
				}
			}
		}
		for(String str : list)
			System.out.println(str);
		reader.close();  
	}
	
	/**
	 * <p>解析属性
	 * 解析属性，然后封装到Map里
	 * @param property
	 * 			要解析的字符串
	 * @return
	 * 	<b>数组:</b>
	 * <p> 
	 * { 颜色, 蝴蝶结类型(鞋花|头饰), 蝴蝶结层数, 是否有钻, 蝴蝶结原料类型, 扣饰类型, 是否为不良品, 规格 }
	 * </p>
	 */
	public void parseProperty(String property) {
		String colorRegEx, typeRegEx, veilRegEx, layerRegEx, rejectRegEx, materialRegEx, pinRegEx, specsRegEx;
		
		// 匹配颜色的正则式
		colorRegEx = "[\u4e00-\u9fa5]*(" + COLORKEYWORDS + ")[色]?";
		
		// 匹配扣饰的正则式
		pinRegEx = "(" + PIN + ")";
		
		// 匹配层数的正则式
		layerRegEx = "(" + LAYERS + ")";
		
		// 匹配类型的正则式
		typeRegEx = "(" + TYPES + ")";
		
		// 匹配材料的正则式
		materialRegEx = "(" + MATERIAL + ")";
		
		veilRegEx = "(" + COLORKEYWORDS + "|蒙)纱";
		
		// 匹配不良品的正则式
		rejectRegEx = "(" + REJECT + ")";
		
		// 匹配规格的正则式
		specsRegEx = "(\\w*\\*\\w*cm|\\d+[\\u4e00-\\u9fa5]*高|高度\\d+[\\u4e00-\\u9fa5]*|宽\\w*\\x20高\\w*|\\w+[\\u4e00-\\u9fa5]*宽)";
		
		// 商品颜色
		color = formateColor(getValue(property, colorRegEx));
		
		// 商品类别
		type = getValue(property, typeRegEx);
		layer = getValue(property, layerRegEx);
		material = getValue(property, materialRegEx);
		veil = getValue(property, veilRegEx);
		pin = getValue(property, pinRegEx);
		reject = getValue(property, rejectRegEx);
		reject = getValue(property, rejectRegEx);
		jewel = getValue(property, "钻");
		specs = width(hwidth(getValue(property, specsRegEx)));
	}
	
	/**
	 * <p>格式化颜色单位
	 * 过滤后的颜色有些没有带单位色，在此可以添加该字
	 * @param color
	 * 			颜色名称
	 * @return
	 * 			添加有'色'字的颜色名称
	 */
	private static String formateColor(String color) {
		if(color != null) {
			if(!color.contains("色")) {
				return color + "色";
			}
			return color;
		}
		return null;
	}
	
	/**
	 * <p>
	 * 根据正则式返回找到的字符串
	 * @param str 
	 * 			要搜索的字符串
	 * @param regEx
	 * 			正则表达式
	 * @return
	 * 			匹配到的字符串
	 */
	private static String getValue(String str, String regEx) {
		Matcher m = null;
		
		Pattern p = Pattern.compile(regEx);
		m = p.matcher(str);
		
		if(m.find()) {
			return str.substring(m.start(), m.end());
		}
		return null;
	}
	
	/**
	 * <p>
	 * <b>拼装格式化规格尺寸</b>
	 * <br>
	 * w * h 正常情况
	 * w * 只有宽的情况
	 * * h 只有高的情况
	 * @param str
	 * @param shape
	 */
	private static String hwidth(String str) {
		if(str != null) {
			// 匹配正则式: 高度28毫米
			if(str.matches("高度\\d+[\\u4e00-\\u9fa5]*")) {
				return "h" + getValue(str, "\\d*毫米");
			} 
			
			// 匹配正则式: 46厘米高
			else if(str.matches("\\w+[\\u4e00-\\u9fa5]*高")) {
				return "h" + getValue(str, "\\w+[\\u4e00-\\u9fa5]*[^高]");
			} 
			
			// 匹配正则式: 下摆最宽12 高9cm
			else if(str.matches("宽\\w*\\x20高\\w*[\\u4e00-\\u9fa5]*")) {
				String h = getValue(str, "\\w+$");
				String w = getValue(str, "宽\\w+[\\u4e00-\\u9fa5]*");
				
				w = getValue(w, "\\w+[\\u4e00-\\u9fa5]*");
				
				return w + "*" + h;
			} 
			
			// 匹配正则式: 13cm宽
			else if(str.matches("\\w+[\\u4e00-\\u9fa5]*宽")) {
				String s = "w" + getValue(str, "\\w+[\\u4e00-\\u9fa5]*[^宽]");
				return s;
			} 
			
			// 匹配正则式: 13*14cm 13cm*13cm
			else {
				return str;
			}
		}
		return null;
	}
	
	/**
	 * <p>
	 * <b>格式化规格尺寸</b>
	 * <br>
	 * 使其成为: 10cm*20cm这种格式
	 * w * h 正常情况
	 * w * 只有宽的情况
	 * * h 只有高的情况
	 * @param width
	 * 		格式化后的规格尺寸
	 */
	private static String width(String width) {
		// 28*110cm, 14cm*16cm, 13cm, 20mm, 46厘米, 9cm, w9cm ,h9cm, 19*32cm, 13*cm
		
		if(width != null) {
			String unit = "";
			
			// h30cm
			if(width.contains("h")) {
				width = formatWidth(width, 'h');
				unit = width.replace('h', '*');
			} 
			// w35cm
			else if(width.contains("w")) {
				width = formatWidth(width, 'w');
				unit = width.replace('w', ' ').trim() + "*";
			} 
			// 35*55cm 35cm*55cm
			else {
				String[] widths = width.split("\\*");
				
				for(int i = 0; i < widths.length; i ++) {
					// 如果数组 i 里没有cm单位,则加上cm
					if(!widths[i].contains("cm")) {
						widths[i] = widths[i] + "cm";
					}
				}
				
				unit = widths[0] + "*" + widths[1];
			}
			return unit;
		}
		return null;
	}
	
	/**
	 * <p>
	 * 格式化输出单位
	 * @param width
	 * @param c
	 * @return
	 */
	private static String formatWidth(String width, char c) {
		if(width.contains("cm")) {
			
		} else if(width.contains("mm") || width.contains("毫米")) {
			int w = Integer.valueOf(getValue(width, "\\d+")) / 10;
			width = c + String.valueOf(w) + "cm";
		} if(width.contains("厘米")) {
			width = width.replace("厘米", "cm");
		} if(width.matches("毫米")) {
			
		}
		
		return width;
	}
	
	/**
	 * 读取文件
	 * @param fileName
	 * 			文件名称
	 * @return
	 *			返回 BufferReader
	 * @throws IOException
	 */
	private BufferedReader readFile(String fileName) throws IOException {
		InputStreamReader irs = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
		return new BufferedReader(irs);
	}
	
	public String getColor() {
		return color;
	}

	public String getType() {
		return type;
	}

	public String getSpecs() {
		return specs;
	}

	public String getLayer() {
		return layer;
	}

	public String getVeil() {
		return veil;
	}

	public String getJewel() {
		return jewel;
	}

	public String getMaterial() {
		return material;
	}

	public String getPin() {
		return pin;
	}

	public String getReject() {
		return reject;
	}
	
	@Override
	public String toString() {
		return "SkuParse [color=" + color + ", specs=" + specs + "]";
	}

	public static void main(String[] args) {
		SkuParse s = new SkuParse("本白色 胸针 13cm*9cm");
		System.out.println(s.pin);
	}
}
